package com.ruoyi.system.service.impl;

import com.ruoyi.common.constant.ConstantsOkr;
import com.ruoyi.common.enums.LikedStatus;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.IpUtils;
import com.ruoyi.common.utils.RedisKeyUtils;
import com.ruoyi.system.domain.LikedCountDTO;
import com.ruoyi.system.domain.OkrCommentMeta;
import com.ruoyi.system.domain.OkrThumbsUp;
import com.ruoyi.system.service.IOkrThumbsUpService;
import com.ruoyi.system.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.ruoyi.common.utils.ServletUtils.getRequest;

/**
 * @author Bruce
 */
@Service
public class IRedisServiceImpl implements IRedisService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    IOkrThumbsUpService thumbsUpService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public void saveLiked2Redis(Long userId, Integer commentId) {
        String key = RedisKeyUtils.getLikedKey(userId, commentId);
        stringRedisTemplate.opsForHash().put(RedisKeyUtils.MAP_USER_LIKE, key, LikedStatus.LIKE.getCode());
    }

    @Override
    public void unlikeFromRedis(Long userId, Integer commentId) {
        String key = RedisKeyUtils.getLikedKey(userId, commentId);
        stringRedisTemplate.opsForHash().put(RedisKeyUtils.MAP_USER_LIKE, key, LikedStatus.UNLIKE.getCode());
    }

    @Override
    public void deleteLikedFromRedis(Long userId, Integer commentId) {
        String key = RedisKeyUtils.getLikedKey(userId, commentId);
        stringRedisTemplate.opsForHash().delete(RedisKeyUtils.MAP_USER_LIKE, key);
    }

    @Override
    public void incrementLikedCount(Integer commentId) {
        //根据评论ID查找Redis里的点赞记录数
        if (stringRedisTemplate.boundHashOps(RedisKeyUtils.MAP_USER_LIKE_COUNT).hasKey(commentId.toString())){
            //记录数+1
            stringRedisTemplate.opsForHash().increment(RedisKeyUtils.MAP_USER_LIKE_COUNT, commentId.toString(), 1);
        }else{
            //找不到就赋值1
            stringRedisTemplate.opsForHash().put(RedisKeyUtils.MAP_USER_LIKE_COUNT, commentId.toString(), "1");
        }

    }

    @Override
    public void decrementLikedCount(Integer commentId) {
        stringRedisTemplate.opsForHash().increment(RedisKeyUtils.MAP_USER_LIKE_COUNT, commentId.toString(), -1);
    }

    @Override
    public OkrThumbsUp containsLikeFromRedis(Long userId, Integer commentId) {
        String key = RedisKeyUtils.getLikedKey(userId, commentId);
        OkrThumbsUp thumbsUp = new OkrThumbsUp();
        Object o = stringRedisTemplate.boundHashOps(RedisKeyUtils.MAP_USER_LIKE).get(key);
        if (o == null) return null;
        thumbsUp.setStatus(Integer.parseInt((String) o));
        thumbsUp.setUserId(userId);
        thumbsUp.setObjectId(commentId);
        return thumbsUp;
    }

    @Override
    public List<OkrThumbsUp> getLikedDataFromRedis() {
        Cursor<Map.Entry<Object, Object>> scan = stringRedisTemplate.opsForHash().scan(RedisKeyUtils.MAP_USER_LIKE, ScanOptions.NONE);
        List<OkrThumbsUp> list = new ArrayList<>();
        while (scan.hasNext()){
            Map.Entry<Object, Object> entry = scan.next();
            String key = (String) entry.getKey();
            String[] thumbs = key.split("::");
            String userId = thumbs[0];
            String commentId = thumbs[1];
            OkrThumbsUp thumbsUp = new OkrThumbsUp();
            thumbsUp.setStatus(Integer.parseInt((String) entry.getValue()));
            thumbsUp.setUserId(Long.parseLong(userId));
            thumbsUp.setObjectId(Integer.parseInt(commentId));
            thumbsUp.setAddTime(DateUtils.getNowDate());
            thumbsUp.setUserIp("");
            list.add(thumbsUp);
            //存到list后删除
            stringRedisTemplate.opsForHash().delete(RedisKeyUtils.MAP_USER_LIKE, key);
        }
        return list;
    }

    @Override
    public String getLikeCountByCommentId(Long commentId) {
        return (String) stringRedisTemplate.boundHashOps(RedisKeyUtils.MAP_USER_LIKE_COUNT).get(commentId.toString());
    }

    @Override
    public List<OkrCommentMeta> getLikedCountFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor = stringRedisTemplate.opsForHash().scan(RedisKeyUtils.MAP_USER_LIKE_COUNT, ScanOptions.NONE);
        List<OkrCommentMeta> list = new ArrayList<>();
        while(cursor.hasNext()){
            Map.Entry<Object, Object> map = cursor.next();
            String key = (String) map.getKey();
            OkrCommentMeta meta = new OkrCommentMeta();
            meta.setCommentId(Integer.parseInt(key));
            meta.setMetaValue((String) map.getValue());
            list.add(meta);
            stringRedisTemplate.opsForHash().delete(RedisKeyUtils.MAP_USER_LIKE_COUNT, key);
        }
        return list;
    }
}
